﻿using System;
using System.Linq;
using System.Web.Mvc;
using Project.DAL.Repository;
using Project.Domain.Entities;

namespace Project.WebUI.Areas.Admin.Controllers
{
    public class ManagebetsController : Controller
    {
        #region "private"
        private readonly IUserRepository _userRepository;
        private readonly IDepositRepository _depositRepository;
        private readonly IWithDrawRepository _withDrawRepository;
        private readonly IUserService _userService;
        private readonly ICountryRepository _countryRepository;
        private readonly IContactRepository _contactRepository;
        private readonly ILeagueRepository _leagueRepository;
        private readonly ISoccerTeamRepository _soccerTeamRepository;
        private readonly IMatchesRepository _matchesRepository;
        private readonly IBetRepository _betRepository;
        private readonly IUserbetRepository _userbetRepository;
        private readonly IStoreSecureRepositoty _storeSecureRepositoty;

        public ManagebetsController(
            IUserRepository userRepository,
            IDepositRepository depositRepository,
            IWithDrawRepository withDrawRepository,
            IUserService userService,
            ICountryRepository countryRepository,
            IContactRepository contactRepository,       
            ILeagueRepository leagueRepository,
            ISoccerTeamRepository soccerTeamRepository,
            IMatchesRepository  matchesRepository,
            IBetRepository betRepository,
            IUserbetRepository userbetRepository,
            IStoreSecureRepositoty storeSecureRepositoty)
        {
            _userRepository = userRepository;
            _depositRepository = depositRepository;
            _withDrawRepository = withDrawRepository;
            _userService = userService;
            _countryRepository = countryRepository;
            _contactRepository = contactRepository;
            _leagueRepository = leagueRepository;
            _soccerTeamRepository = soccerTeamRepository;
            _matchesRepository = matchesRepository;
            _betRepository = betRepository;
            _userbetRepository = userbetRepository;
            _storeSecureRepositoty = storeSecureRepositoty;
        }

        #endregion                

        public ActionResult Index()
        {
            return View();
        }
        public ActionResult ListallLeague()
        {
            var league = _leagueRepository.GetMany(null, l => l.OrderByDescending(n => n.NameLeague));
            ViewBag.league = new SelectList(league.ToList(), "LeagueId", "NameLeague");
            return View(league);
        }

        public ActionResult Listmatches()
        {
            ViewBag.HomeTeamID = new SelectList(_soccerTeamRepository.GetAll(), "TeamID", "TeamName");
            ViewBag.AwayTeamID = new SelectList(_soccerTeamRepository.GetAll(), "TeamID", "TeamName");
            ViewBag.LeagueId = new SelectList(_soccerTeamRepository.GetAll(), "LeagueId", "NameLeague");            
            return View();
        }

        [HttpPost]
        public ActionResult InsertMatch(Match matchmodel)
        {
            if (ModelState.IsValid)
            {
                var newmatch = new Match
                                   {
                                       AwayTeam = matchmodel.AwayTeam,
                                       HomeTeam = matchmodel.HomeTeam,
                                       LeagueId = matchmodel.LeagueId,                                       
                                       Status = true
                                   };
                _matchesRepository.Add(newmatch);
                var league = _leagueRepository.Get(l => l.LeagueId == matchmodel.LeagueId);
                league.IsPlay = true;
                _matchesRepository.SaveChanges();                
                return RedirectToAction("Listmatches");
            }

            ViewBag.HomeTeamID = new SelectList(_soccerTeamRepository.GetAll(), "TeamID", "TeamName");
            ViewBag.AwayTeamID = new SelectList(_soccerTeamRepository.GetAll(), "TeamID", "TeamName");
            ViewBag.LeagueId = new SelectList(_soccerTeamRepository.GetAll(), "LeagueId", "NameLeague");            
            return View("listmatches",matchmodel);
        }


        public ActionResult GetAllMatchesByLeagueId(int leagueId)
        {
            var listmatch = _matchesRepository.GetMany(m => m.LeagueId == leagueId,
                                                       m => m.OrderByDescending(t => t.CreatedTime));                                                
            return PartialView("_getAllMatchesByLeagueId", listmatch);
        }

        public ActionResult ListAllMatches()
        {
            var lisalltmatch =_matchesRepository.GetAll().OrderByDescending(m=>m.CreatedTime).ThenBy(m=>m.Status);               
            return PartialView("_ListAllMatches", lisalltmatch);
        }


        [HttpGet]
        public ActionResult InsertTeam()
        {
            return View();
        }

        [HttpPost]
        public ActionResult InsertTeam(SoccerTeam soccerteam)
        {
            _soccerTeamRepository.Add(soccerteam);
            _soccerTeamRepository.SaveChanges();
            return View();
        }

        [HttpGet]
        public ActionResult Insertleague()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Insertleague(League leaguemodel)
        {
            if (!ModelState.IsValid)
            {
                ModelState.AddModelError("", "Tên giải đấu không được bỏ trống");
                return View(leaguemodel);
            }
            var league = _leagueRepository.Get(l => l.NameLeague.Equals(leaguemodel.NameLeague));

            if (league != null)
            {
                ModelState.AddModelError("", "trùng tên vui lòng kiểm tra lại!");
                return View(leaguemodel);
            }
            var newleague = new League
                                {
                                    NameLeague = leaguemodel.NameLeague,
                                    IsPlay = false
                                };
            _leagueRepository.Add(newleague);
            _leagueRepository.SaveChanges();
            return RedirectToAction("ListallLeague");
        }

        //start match ok
        public ActionResult Startmatch(int id)
        {
            var match = _matchesRepository.GetById(id);
            if (match != null) 
                match.Status = true;
            _matchesRepository.SaveChanges();
            var league = _leagueRepository.GetById(match.LeagueId);

            var listmatchesofLeague = _matchesRepository.GetMany(l => l.LeagueId == league.LeagueId);
            
            var countmatchesofleague = listmatchesofLeague.Count();
            
            if (countmatchesofleague == 0)
            {
                league.IsPlay =false;
                _leagueRepository.SaveChanges();
            }
            
            return RedirectToAction("Listmatches");
        }

        public ActionResult Endmatch(int id)
        {
            var matchmodel = _matchesRepository.GetById(id);
            return View(matchmodel);
        }

        [HttpPost]
        public ActionResult Endmatch(Match matchmodel)
        {
            if (ModelState.IsValid)
            {
                //update match
                var matchupdate = _matchesRepository.GetById(matchmodel.MatchId);
                matchupdate.HomeScore = matchmodel.HomeScore;
                matchupdate.AwayScore = matchmodel.AwayScore;
                matchupdate.EndTime = DateTime.Now;
                matchupdate.IsPlay = 1;//end match
                
                //list all bet of matches
                var listbethasmatchid = _betRepository.GetMany(bet => bet.MatchId == matchupdate.MatchId);
                foreach (var bet in listbethasmatchid)
                {
                    //update bet
                    bet.ScoreHomeAfter = matchmodel.HomeScore;
                    bet.ScoreAwayAfter = matchmodel.AwayScore;                    

                    //list all userbet has status=true                    
                    var listuserbetofbet = 
                        _userbetRepository.GetMany(ub => 
                            ub.BetDetail.BetId == bet.BetId && ub.Status);
                    
                    //list all userbet has status=false;
                    var listuserbetnotTrueofbet =
                        _userbetRepository.GetMany(
                            userbetnotTrueofbet =>
                            userbetnotTrueofbet.BetDetail.BetId == bet.BetId && userbetnotTrueofbet.Status == false);
                    
                    //del all userbet has status=false;
                    foreach (var item in listuserbetnotTrueofbet)
                    {
                        _userbetRepository.Delete(item);
                        _userbetRepository.SaveChanges();
                    }
                    
                    switch (bet.Type)
                    {
                        //bet 3way : win,draw,lose
                        case 1:
                            {
                                var subscore = Convert.ToInt32(bet.ScoreHomeAfter - bet.ScoreAwayAfter);
                                foreach (var userbet in listuserbetofbet)
                                {
                                    var user = _userRepository.GetUserById(userbet.UserId);
                                    // if home win
                                    if (subscore > 0)
                                    {
                                        //update balance for userbet home
                                        if (userbet.BetDetail.Type == 1)
                                        {
                                            userbet.UserWin = userbet.Odds*userbet.Stake;
                                            user.Balance += Convert.ToDecimal(userbet.UserWin);
                                        }
                                    }

                                        //draw win
                                    else if (subscore == 0)
                                    {
                                        //update balance for userbet draw
                                        if (userbet.BetDetail.Type == 2)
                                        {
                                            userbet.UserWin = userbet.Odds*userbet.Stake;
                                            user.Balance += Convert.ToDecimal(userbet.UserWin);
                                        }
                                    }
                                        //away win
                                    else
                                    {
                                        //update balance for userbet away
                                        if (userbet.BetDetail.Type == 3)
                                        {
                                            userbet.UserWin = userbet.Odds*userbet.Stake;
                                            user.Balance += Convert.ToDecimal(userbet.UserWin);
                                        }
                                    }
                                }
                            }
                            break;

                        //bet 3way handicap : chap truoc gom co win,draw,lose
                        case 2:
                            {
                                //subscore
                                var subscore =
                                    Convert.ToDecimal((bet.ScoreHomeAfter + bet.ScoreHomeBefore) -
                                                      (bet.ScoreAwayAfter + bet.ScoreAwayBefore));
                                foreach (var userbet in listuserbetofbet)
                                {
                                    var user = _userRepository.GetUserByName(User.Identity.Name);
                                    //hom win
                                    if (subscore > 0)
                                    {
                                        //update balance for userbet home
                                        if (userbet.BetDetail.Type == 1)
                                        {
                                            userbet.UserWin = userbet.Odds*userbet.Stake;
                                            user.Balance += Convert.ToDecimal(userbet.UserWin);
                                        }
                                    }
                                        //draw win
                                    else if (subscore == 0)
                                    {
                                        //update balance for userbet draw
                                        if (userbet.BetDetail.Type == 2)
                                        {
                                            userbet.UserWin = userbet.Odds*userbet.Stake;
                                            user.Balance += Convert.ToDecimal(userbet.UserWin);
                                        }
                                    }
                                        //away win
                                    else
                                    {
                                        //update balance for userbet home
                                        if (userbet.BetDetail.Type == 3)
                                        {
                                            userbet.UserWin = userbet.Odds*userbet.Stake;
                                            user.Balance += Convert.ToDecimal(userbet.UserWin);
                                        }
                                    }
                                }
                            }
                            break;

                        //Asian Handicap chap truoc chi co win,lose
                        case 3:
                            {
                                var subscore =
                                    Convert.ToDecimal((bet.ScoreHomeAfter + bet.ScoreHomeBefore) -
                                                      (bet.ScoreAwayAfter + bet.ScoreAwayBefore));
                                foreach (var userbet in listuserbetofbet)
                                {
                                    var user = _userRepository.GetUserByName(User.Identity.Name);
                                    //hom win
                                    if (subscore > 0)
                                        //update balance for userbet home
                                        if (userbet.BetDetail.Type == 1)
                                        {
                                            userbet.UserWin = userbet.Odds*userbet.Stake;
                                            user.Balance += Convert.ToDecimal(userbet.UserWin);
                                        }
                                    //away win
                                    if (subscore < 0)
                                        //update balance for userbet home
                                        if (userbet.BetDetail.Type == 2)
                                        {
                                            userbet.UserWin = userbet.Odds*userbet.Stake;
                                            user.Balance += Convert.ToDecimal(userbet.UserWin);
                                        }
                                }
                            }
                            break;

                        //under/over :duoi tren.
                        case 4:
                            {
                                var sumscore = Convert.ToInt32(bet.ScoreHomeAfter + bet.ScoreAwayAfter);
                                foreach (var userbet in listuserbetofbet)
                                {
                                    var user = _userRepository.GetUserByName(User.Identity.Name);
                                    //under
                                    if (userbet.BetDetail.Type == 1)
                                    {
                                        //least than 
                                        if (userbet.BetDetail.RateUnderOver > sumscore)
                                        {
                                            userbet.UserWin = userbet.Odds*userbet.Stake;
                                            user.Balance += Convert.ToDecimal(userbet.UserWin);
                                        }
                                    }

                                        //over
                                    else
                                    {
                                        if (sumscore < userbet.BetDetail.RateUnderOver)
                                        {
                                            userbet.UserWin = userbet.Odds*userbet.Stake;
                                            user.Balance += Convert.ToDecimal(userbet.UserWin);
                                        }
                                    }
                                }
                            }
                            break;

                        //exact score: win,lose
                        case 5:
                            foreach (var userbet in listuserbetofbet)
                            {
                                var user = _userRepository.GetUserByName(User.Identity.Name);
                                //exacterly 
                                if (userbet.BetDetail.Bet.ScoreHomeBefore == bet.ScoreHomeBefore &&
                                    userbet.BetDetail.Bet.ScoreAwayBefore == bet.ScoreAwayBefore)
                                {
                                    userbet.UserWin = userbet.Odds*userbet.Stake;
                                    user.Balance += Convert.ToDecimal(userbet.UserWin);
                                }
                            }
                            break;
                    }
                }
                _userbetRepository.SaveChanges();                           
            }
            return RedirectToAction("Listmatches");
        }

    }
}
